package org.microboot.data.factory;

import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.collect.Maps;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.Assert;

import javax.sql.DataSource;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * @author 胡鹏
 *
 * 老版本：
 * 是否开启分布式事务的是enableXA属性来决定的
 * DruidDataSourceFactory在创建DataSource对象时，根据enableXA属性判断是否创建DruidXADataSource和AtomikosDataSourceBean
 *
 * 新版本：
 * 在microboot-framework-data-xa包中重新实现DataSourceFactory，即：DruidXADataSourceFactory，覆盖掉DruidDataSourceFactory
 * 将创建DruidXADataSource和AtomikosDataSourceBean的逻辑都移交到XA包中去，让Data包中的代码更干净，更纯粹，即：默认不支持分布式事务
 * 如果要使用分布式事务，只需要引入microboot-framework-data-xa包即可
 */
@ConfigurationProperties(prefix = "datasource")
public class DruidDataSourceFactory implements DataSourceFactory {

    //macro文件名
    private String macro;

    //写数据库连接池信息
    private Map<String, Object> master;

    //读数据库连接池信息
    private Map<String, Object> slaves;

    //其他数据库连接池信息
    private List<Map<String, Object>> others;

    //DruidDataSource配置项前缀
    private final String prefix = "druid.";

    @Override
    public boolean getEnableXA() {
        return false;
    }

    @Override
    public String getMacro() {
        return macro;
    }

    public void setMacro(String macro) {
        this.macro = macro;
    }

    @Override
    public Map<String, Object> getMaster() {
        return master;
    }

    public void setMaster(Map<String, Object> master) {
        this.master = master;
    }

    @Override
    public Map<String, Object> getSlaves() {
        return slaves;
    }

    public void setSlaves(Map<String, Object> slaves) {
        this.slaves = slaves;
    }

    @Override
    public List<Map<String, Object>> getOthers() {
        return others;
    }

    public void setOthers(List<Map<String, Object>> others) {
        this.others = others;
    }

    /**
     * 创建DruidDataSource或DruidXADataSource
     *
     * @param parameters
     * @return
     */
    public DataSource createDataSource(Map<String, Object> parameters) {
        //连接池配置
        Map<String, Object> dataSourceMap = Maps.newHashMap();
        //master是默认配置
        dataSourceMap.putAll(master);
        //parameters是差异化配置，可覆盖或补全master中相同的key的value
        dataSourceMap.putAll(parameters);

        //创建连接池对象
        DruidDataSource druidDataSource = new DruidDataSource();

        //封装连接池配置
        Properties properties = new Properties();
        for (String key : dataSourceMap.keySet()) {
            String value = MapUtils.getString(dataSourceMap, key);
            if (StringUtils.isBlank(value)) {
                continue;
            }
            properties.setProperty(prefix + key, value);
        }

        //初始化连接池配置
        druidDataSource.configFromPropety(properties);

        return druidDataSource;
    }

    /**
     * 获取数据源名称
     *
     * @param dataSource
     * @return
     */
    public String getDataSourceName(DataSource dataSource) {
        Assert.isTrue(dataSource != null, "dataSourceName is null");
        return ((DruidDataSource) dataSource).getName();
    }
}